package com.loongtech.bi.synch;

import com.loongtech.bi.entity.system.EntityBiServer;
import com.loongtech.bi.manager.system.BiPlatformManager;
import com.loongtech.bi.manager.system.BiServerManager;
import com.loongtech.bi.support.Log;
import org.datanucleus.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 使用http方式同步游戏的server数据和平台数据
 * 
 * @author xckuang
 * @date 2014年12月19日
 */
public class DataManager {
	private DataManager() {}

	private static DataManager instance = new DataManager();

	public static DataManager instance() {
		return instance;
	}

	/**
	 * 初始化数据
	 */
	public void initData(BiPlatformManager platformManager) {
		try {
			if (null != platformManager) {
				platformManager.init();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			Log.bi.error("DataManager initData ", ex);
		}
	}

	private List<Element> getServerList(Element serverNode) {
		List<Element> list = new ArrayList<>();
		if (null == serverNode || null == serverNode.getChildNodes()) {
			return list;
		}

		// 为了支持台湾和东方不得不这样解析了
		NodeList nodeList = serverNode.getElementsByTagName("server");
		if (null != nodeList && nodeList.getLength() > 0) {
			for (int index = 0, size = nodeList.getLength(); index < size; ++index) {
				Node node = nodeList.item(index);
				if (null != node && node.getNodeType() == Node.ELEMENT_NODE) {
					list.add((Element) node);
				}
			}
			return list;
		}

		// 东方格式
		NodeList gameList = serverNode.getChildNodes();
		for (int index0 = 0, size0 = gameList.getLength(); index0 < size0; ++index0) {
			Node g = gameList.item(index0);
			if (null == g || !"game".equals(g.getNodeName()) || g.getNodeType() != Node.ELEMENT_NODE) {
				continue;
			}
			NodeList zoneList = g.getChildNodes();
			for (int index1 = 0, size1 = zoneList.getLength(); index1 < size1; ++index1) {
				Node z = zoneList.item(index1);
				if (null == z || !"zone".equals(z.getNodeName()) || z.getNodeType() != Node.ELEMENT_NODE) {
					continue;
				}
				NodeList servList = z.getChildNodes();
				for (int index2 = 0, size2 = servList.getLength(); index2 < size2; ++index2) {
					Node s = servList.item(index2);
					if (null == s || !"server".equals(s.getNodeName()) || s.getNodeType() != Node.ELEMENT_NODE) {
						continue;
					}
					list.add((Element) s);
				}
			}
		}
		return list;
	}

	private Map<String, EntityBiServer> getServerMap(String serverInfo) {
		Map<String, EntityBiServer> newMap = new LinkedHashMap<>();
		try {
			InputSource is = new InputSource(new StringReader(serverInfo));
			Element root = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement();
            String gameId = root.getAttribute("gameid");
			for (Element item : getServerList(root)) {
				String hidden = item.getAttribute("hidden");
				if (!"false".equals(hidden)) {
					continue;
				}
				String id = item.getAttribute("zoneid");
				String name = item.getAttribute("name");
				String desc = item.getAttribute("ip");
				if (null == id || id.trim().isEmpty() || null == name || name.trim().isEmpty()) {
					Log.bi.error("DataSyncher syncData id or name is null !");
					continue;
				}
				EntityBiServer server = new EntityBiServer();
                server.setGameId(StringUtils.isEmpty(gameId) ? 0 : Integer.parseInt(gameId));
				server.setId(id);
				server.setName(name);
				server.setDescription(null != desc ? desc : name);
				newMap.put(id, server);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			Log.bi.error("DataManager getServerMap ", ex);
		}

		return newMap;
	}

	/**
	 * 更新游戏的服务器信息
	 * 
	 * @param serverManager
	 * @param serverInfo
	 */
	public void updateServer(BiServerManager serverManager, BiPlatformManager platformManager, String serverInfo) {
		if (null == serverInfo || serverInfo.trim().isEmpty()) {
			Log.bi.error("DataManager updateServer serverInfo is empty !");
			return;
		}

		Map<String, EntityBiServer> newMap = getServerMap(serverInfo);
		if (null == newMap || newMap.isEmpty()) {
			Log.bi.error("DataManager updateServer newMap is empty ! serverInfo={}", serverInfo);
			return;
		}

		for (EntityBiServer server : newMap.values()) {
			if (null == server || null == server.getId() || null == server.getName()) {
				Log.bi.error("DataManager updateServer server info error ! server={}", server);
				continue;
			}

			serverManager.insertOrUpdate(server);
		}

		// 更新缓存
		initData(platformManager);
	}
}
